package clipboard

import (
	"context"
	"strings"

	"golang.design/x/clipboard"

	"clipboard-tray/common/link"
	log "clipboard-tray/common/log"
)

type ClipBoard struct {
	ctx    context.Context
	Buffer *link.Link
	ClipBoardConfig
	logger *log.Log
}

type ClipBoardConfig struct {
	NoSpace    bool `ini:"nospace"`
	PopUp      bool `ini:"popup"`
	Persist    bool `ini:"persist"`
	MaxPersist int  `ini:"maxpersist"`
}

// NewClipBoardConfig 提供默认配置
func NewClipBoardConfig() *ClipBoardConfig {
	return &ClipBoardConfig{
		NoSpace:    true,
		Persist:    false,
		PopUp:      true,
		MaxPersist: 5,
	}
}

// Validate 参数校验
func (c *ClipBoardConfig) Validate() {
	if c.MaxPersist < 5 {
		c.MaxPersist = 5
	}
	if c.MaxPersist > 10 {
		c.MaxPersist = 10
	}
}

func NewClipBoard(ctx context.Context, config ClipBoardConfig, logger *log.Log) *ClipBoard {
	return &ClipBoard{
		ctx:             ctx,
		Buffer:          link.NewLink(config.MaxPersist),
		ClipBoardConfig: config,
		logger:          logger,
	}
}

// InitWatcher 初始化一个监视器
func (c *ClipBoard) InitWatcher(updateChan chan<- struct{}) {
	changed := clipboard.Watch(context.Background(), clipboard.FmtText)
	for txt := range changed {
		c.logger.Info("Detected clipboard input")
		str := string(txt)
		if c.NoSpace {
			str = strings.TrimSpace(str)
		}
		// 0 是否是旧数据
		node := c.Buffer.FindNode(str)
		// 1 是旧节点，弹出到尾部
		if node != nil {
			if c.PopUp && node.Next != nil {
				c.Buffer.PopNode(node)
				c.logger.Debug("add old node to tail")
				updateChan <- struct{}{}
				continue
			}
			c.Buffer.ShowLink()
			continue
		}
		// 2 不是旧节点
		// 2.1 缓存满，先删除第一个数据，再尾插
		if c.Buffer.IsFull() {
			c.Buffer.Del(c.Buffer.GetFirstNode().GetData())
		}
		// 2.2 缓存不满，不需要删除第一个数据，直接尾插
		c.Buffer.Add(link.NewNode(str))
		c.logger.Debug("add new node to tail")
		updateChan <- struct{}{}
		continue
	}
}
